<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta http-equiv="content-type" content="text/html; charset=utf-8" />
    <script type="text/javascript" src="https://cdn.staticfile.org/jquery/3.2.1/jquery.min.js"></script>
    <script src="js/highlight.pack.js"></script>
    <script>
        hljs.initHighlightingOnLoad();
    </script>
    <!-- 最新版本的 Bootstrap 核心 CSS 文件 -->
    <link rel="stylesheet" href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">

    <!-- 可选的 Bootstrap 主题文件（一般不用引入） -->
    <link rel="stylesheet" href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap-theme.min.css" integrity="sha384-rHyoN1iRsVXV4nD0JutlnGaslCJuC7uwjduW9SVrLvRYooPp2bWYgmgJQIXwl/Sp" crossorigin="anonymous">

    <!-- 最新的 Bootstrap 核心 JavaScript 文件 -->
    <script src="https://cdn.bootcss.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
    <link rel="stylesheet" href="styles/agate.css">
    <style>
        /* Custom Styles */
        ul.nav-tabs{
            width: 140px;
            margin-top: 20px;
            border-radius: 4px;
            border: 1px solid #ddd;
            box-shadow: 0 1px 4px rgba(0, 0, 0, 0.067);
        }
        ul.nav-tabs li{
            margin: 0;
            border-top: 1px solid #ddd;
        }
        ul.nav-tabs li:first-child{
            border-top: none;
        }
        ul.nav-tabs li a{
            margin: 0;
            padding: 8px 16px;
            border-radius: 0;
        }
        ul.nav-tabs li.active a, ul.nav-tabs li.active a:hover{
            color: #fff;
            background: #0088cc;
            border: 1px solid #0088cc;
        }
        ul.nav-tabs li:first-child a{
            border-radius: 4px 4px 0 0;
        }
        ul.nav-tabs li:last-child a{
            border-radius: 0 0 4px 4px;
        }
        ul.nav-tabs.affix{
            top: 100px; /* Set the top position of pinned element */
        }
        p{ text-indent:2em;}
    </style>
    <title>设计原则</title>
</head>
<body data-spy="scroll" data-target="#myScrollspy" data-offset="20" style="padding-top: 70px;">

<nav class="navbar navbar-default navbar-fixed-top">
    <div class="container">
        <div class="navbar-header">
            <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1" aria-expanded="false">
            </button>
            <a class="navbar-brand" href="welcome.jsp"><strong>设计模式</strong></a>
        </div>
        <div class="navbar-right">
            <p class="navbar-text">【管理员】 <a href="log_suc.jsp" class="navbar-link">徐传鹏</a></p>
            <button type="button" class="btn btn-default navbar-btn " onclick="check()">注销</button>
        </div>
    </div>
</nav>


<div class="container">
    <div class="row">
        <div class="page-header" style="width:50%;margin:0 auto">
            <h1>六大设计原则<small>&nbsp;实际有七个...</small></h1>
        </div>
        <div class="col-xs-2" id="myScrollspy">
            <ul class="nav nav-tabs nav-stacked affix" data-spy="affix" data-offset-top="125">
                <li class="active"><a href="#section-1">单一职责原则</a></li>
                <li><a href="#section-2">开闭原则</a></li>
                <li><a href="#section-3">里氏代换原则</a></li>
                <li><a href="#section-4">依赖倒转原则</a></li>
                <li><a href="#section-5">合成/聚合复用原则</a></li>
                <li><a href="#section-6">迪米特法则</a></li>
                <li><a href="#section-7">接口隔离法则</a></li>
            </ul>
        </div>

        <div class="col-xs-7">
            <div class="panel panel-default">
                <div class="panel-heading">
                    <h3 id="section-1" class="panel-title">单一职责原则(Single Responsibility Principle,SRP)</h3>
                </div>
                <div class="panel-body">
                    <p><strong>类的职责要单一，不能将太多的职责放在一个类中。（高内聚、低耦合）。</strong></p>
                    <h3>定义：</h3>
                    <p>一个对象应该只包含单一的职责，并且该职责被完整地封装在一个类中。（Every object should have a single responsibility, and that responsibility should be entirely encapsulated by the class.），即又定义有且仅有一个原因使类变更。</p>
                    <h3>例子：</h3>
                    <p>一个数据结构职责类和算法行为都放在一个类User。我们应该把数据结构和行为分开。现使用单一职责原则对User类进行重构。</p>
                    <img src="images/six-Single.jpg" style="width: 100%">
                    <h3>优点：</h3>
                    <p>1、降低类的复杂性，类的职责清晰明确。比如数据职责和行为职责清晰明确。<br>
                        2、提高类的可读性和维护性，<br>
                        3、变更引起的风险减低，变更是必不可少的，如果接口的单一职责做得好，一个接口修改只对相应的类有影响，对其他接口无影响，这对系统的扩展性、维护性都有非常大的帮助。<br>
                        <strong>注意：</strong>单一职责原则提出了一个编写程序的标准，用“职责”或“变化原因”来衡量接口或类设计得是否合理，但是“职责”和“变化原因”都是没有具体标准的，一个类到底要负责那些职责？这些职责怎么细化？细化后是否都要有一个接口或类？这些都需从实际的情况考虑。因项目而异，因环境而异。</p>
                </div>
            </div>

            <div class="panel panel-default">
                <div class="panel-heading">
                    <h3 id="section-2" class="panel-title">开放封闭原则( Open - ClosedPrinciple ,OCP )</h3>
                </div>
                <div class="panel-body">
                    <p><strong>对扩展开放，对修改关闭</strong></p>
                    <h3>定义：</h3>
                    <p>一个软件实体(如类、模块和函数)应该对扩展开放，对修改关闭.  意思是,在一个系统或者模块中,对于扩展是开放的,对于修改是关闭的,一个 好的系统是在不修改源代码的情况下,可以扩展你的功能. 而实现开闭原则的关键就是抽象化.</p>
                    <h3>关键：</h3>
                    <p>1、降低类的复杂性，类的职责清晰明确。比如数据职责和行为职责清晰明确。<br>
                        2)实现开闭原则的关键就是抽象化 <br>
                        3)可变性的封闭原则:找到系统的可变因素,将它封装起来</p>
                    <p><strong>模板方法模式和观察者模式都是开闭原则的极好体现。</strong></p>
                </div>
            </div>

            <div class="panel panel-default">
                <div class="panel-heading">
                    <h3 id="section-3" class="panel-title">里氏代换原则( Liskov Substitution Principle ,LSP )</h3>
                </div>
                <div class="panel-body">
                    <p><strong>任何基类可以出现的地方,子类也可以出现</strong></p>
                    <h3>定义：</h3>
                    <p>所有引用基类（父类）的地方必须能透明地使用其子类的对象。即子类能够必须能够替换基类能够从出现的地方。子类也能在基类 的基础上新增行为。</p>
                    <h3>关键：</h3>
                    <p>1、讲的是基类和子类的关系，只有这种关系存在时，里氏代换原则才存在。<br>
                        2、里氏代换原则可以通俗表述为：在软件中如果能够使用基类对象，那么一定能够使用其子类对象<br>
                        3、里氏代换原则是实现开闭原则的重要方式之一，由于使用基类对象的地方都可以使用子类对象，因此在程序中尽量使用基类类型来对对象进行定义，而在运行时再确定其子类类型，用子类对象来替换父类对象。<br>
                        </p>
                </div>
            </div>

            <div class="panel panel-default">
                <div class="panel-heading">
                    <h3 id="section-4" class="panel-title">依赖倒转原则( Dependence Inversion Principle ,DIP )</h3>
                </div>
                <div class="panel-body">
                    <p><strong>要依赖抽象,而不要依赖具体的实现.</strong></p>
                    <h3>定义：</h3>
                    <p>高层模块不应该依赖低层模块，它们都应该依赖抽象。抽象不应该依赖于细节，细节应该依赖于抽象。简单的说，依赖倒置原则要求客户端依赖于抽象耦合。</p>
                    <p><strong></strong></p>
                    <h3>例子：</h3>
                    <p>一个数据结构职责类和算法行为都放在一个类User。我们应该把数据结构和行为分开。现使用单一职责原则对User类进行重构。<br>
                        1）抽象不应当依赖于细节；细节应当依赖于抽象；<br>
                        2）要针对接口编程，不针对实现编程。
                    </p>
                    <h3>优点：</h3>
                    <p>采用依赖倒置原则可以减少类间的耦合性，提高系统的稳定性，降低并行开发引起的风险，提高代码的可读性和可维护性。</p>
                </div>
            </div>

            <div class="panel panel-default">
                <div class="panel-heading">
                    <h3 id="section-5" class="panel-title">合成/聚合复用原则(Composite/Aggregate ReusePrinciple ，CARP)</h3>
                </div>
                <div class="panel-body">
                    <p><strong>要尽量使用对象组合,而不是继承关系达到软件复用的目的。</strong></p>
                    <h3>定义：</h3>
                    <p>经常又叫做合成复用原则（Composite ReusePrinciple或CRP），尽量使用对象组合，而不是继承来达到复用的目的。</p>
                    <p>继承复用：实现简单，易于扩展。破坏系统的封装性；从基类继承而来的实现是静态的，不可能在运行时发生改变，没有足够的灵活性；只能在有限的环境中使用（“白箱”复用）。<br>
                        组合/聚合复用：耦合度相对较低，选择性地调用成员对象的操作；可以在运行时动态进行。（“黑箱”复用）</p>
                    <p>组合/聚合可以使系统更加灵活，类与类之间的耦合度降低，一个类的变化对其他类造成的影响相对较少，因此一般首选使用组合/聚合来实现复用；其次才考虑继承，在使用继承时，需要严格遵循里氏代换原则，有效使用继承会有助于对问题的理解，降低复杂度，而滥用继承反而会增加系统构建和维护的难度以及系统的复杂度，因此需要慎重使用继承复用。</p>
                    <p>此原则和里氏代换原则氏相辅相成的,两者都是具体实现"开-闭"原则的规范。违反这一原则，就无法实现"开-闭"原则</p>
                </div>
            </div>

            <div class="panel panel-default">
                <div class="panel-heading">
                    <h3 id="section-6" class="panel-title">迪米特法则(Law of Demeter，LoD)</h3>
                </div>
                <div class="panel-body">
                    <p><strong>系统中的类,尽量不要与其他类互相作用,减少类之间的耦合度。</strong></p>
                    <h3>定义：</h3>
                    <p>又叫最少知识原则（Least Knowledge Principle或简写为LKP）几种形式定义：<br>
                        (1) 不要和“陌生人”说话。英文定义为：Don't talk to strangers.<br>
                        (2) 只与你的直接朋友通信。英文定义为：Talk only to your immediatefriends.<br>
                        (3) 每一个软件单位对其他的单位都只有最少的知识，而且局限于那些与本单位密切相关的软件单位。<br>
                        简单地说，也就是，一个对象应当对其它对象有尽可能少的了解。一个类应该对自己需要耦合或调用的类知道得最少
                    </p>
                    <p><strong>例子：</strong>外观模式</p>
                </div>
            </div>

            <div class="panel panel-default">
                <div class="panel-heading">
                    <h3 id="section-7" class="panel-title">接口隔离法则(Interface Segregation Principle，ISL）</h3>
                </div>
                <div class="panel-body">
                    <p><strong>客户端不应该依赖那些它不需要的接口。</strong></p>
                    <h3>定义：</h3>
                    <p>客户端不应该依赖那些它不需要的接口。</p>
                    <p><strong></strong></p>
                    <h3>例子：</h3>
                    <p>下图展示了一个拥有多个客户类的系统，在系统中定义了一个巨大的接口（胖接口）AbstractService来服务所有的客户类。可以使用接口隔离原则对其进行重构。</p>
                    <p>重构前：</p>
                    <img src="images/sixInterface.png" style="width: 100%">
                    <p>重构后：</p>
                    <img src="images/sixInterface2.png" style="width: 100%">
                    <p>迪米特法则是目的,而接口隔离法则是对迪米特法则的规范. 为了做到尽可能小的耦合性,我们需要使用接口来规范类,用接口来约束类.要达到迪米特法则的要求,最好就是实现接口隔离法则,实现接口隔离法则,也就满足了迪米特法则。</p>
                </div>
            </div>

        </div>

        <div id="list" class="col-xs-3">
            <ul class="list-group"  style="width:90%;float:right">
                <h3>模式列表</h3>
                <li class="list-group-item"><strong>----------创建型模式------------</strong></li>
                <li class="list-group-item"><a href="${pageContext.request.contextPath}/JServlet?actionName=pattern&pid=2">工厂模式</a></li>
                <li class="list-group-item"><a href="${pageContext.request.contextPath}/JServlet?actionName=pattern&pid=3">抽象工厂模式</a></li>
                <li class="list-group-item"><a href="${pageContext.request.contextPath}/JServlet?actionName=pattern&pid=4">单例模式</a></li>
                <li class="list-group-item"><a href="${pageContext.request.contextPath}/JServlet?actionName=pattern&pid=5">建造者模式</a></li>
                <li class="list-group-item"><a href="${pageContext.request.contextPath}/JServlet?actionName=pattern&pid=6">原型模式</a></li>
                <li class="list-group-item"><strong>----------结构型模式------------</strong></li>
                <li class="list-group-item"><a href="${pageContext.request.contextPath}/JServlet?actionName=pattern&pid=7">适配器模式</a></li>
                <li class="list-group-item"><a href="${pageContext.request.contextPath}/JServlet?actionName=pattern&pid=8">桥接模式</a></li>
                <li class="list-group-item"><a href="${pageContext.request.contextPath}/JServlet?actionName=pattern&pid=9">过滤器模式</a></li>
                <li class="list-group-item"><a href="${pageContext.request.contextPath}/JServlet?actionName=pattern&pid=10">组合模式</a></li>
                <li class="list-group-item"><a href="${pageContext.request.contextPath}/JServlet?actionName=pattern&pid=11">装饰模式</a></li>
                <li class="list-group-item"><a href="${pageContext.request.contextPath}/JServlet?actionName=pattern&pid=12">外观模式</a></li>
                <li class="list-group-item"><a href="${pageContext.request.contextPath}/JServlet?actionName=pattern&pid=13">享元模式</a></li>
                <li class="list-group-item"><a href="${pageContext.request.contextPath}/JServlet?actionName=pattern&pid=14">代理模式</a></li>
                <li class="list-group-item"><strong>----------行为型模式------------</strong></li>
                <li class="list-group-item"><a href="${pageContext.request.contextPath}/JServlet?actionName=pattern&pid=15">迭代器模式</a></li>
                <li class="list-group-item"><a href="${pageContext.request.contextPath}/JServlet?actionName=pattern&pid=16">策略模式</a></li>
                <li class="list-group-item"><a href="${pageContext.request.contextPath}/JServlet?actionName=pattern&pid=17">观察者模式</a></li>
                <li class="list-group-item"><a href="${pageContext.request.contextPath}/JServlet?actionName=pattern&pid=18">状态模式</a></li>
                <li class="list-group-item"><a href="${pageContext.request.contextPath}/JServlet?actionName=pattern&pid=19">备忘录模式</a></li>
                <li class="list-group-item"><a href="${pageContext.request.contextPath}/JServlet?actionName=pattern&pid=20">命令模式</a></li>
                <li class="list-group-item"><a href="${pageContext.request.contextPath}/JServlet?actionName=pattern&pid=21">职责链模式</a></li>
                <li class="list-group-item"><a href="${pageContext.request.contextPath}/JServlet?actionName=pattern&pid=22">中介者模式</a></li>
                <li class="list-group-item"><a href="${pageContext.request.contextPath}/JServlet?actionName=pattern&pid=23">解释器模式</a></li>
                <li class="list-group-item"><a href="${pageContext.request.contextPath}/JServlet?actionName=pattern&pid=24">访问者模式</a></li>
                <li class="list-group-item"><a href="${pageContext.request.contextPath}/JServlet?actionName=pattern&pid=25">模板方法模式</a></li>
                <li class="list-group-item"><a href="${pageContext.request.contextPath}/JServlet?actionName=pattern&pid=26">------------六大原则------------</a></li>
                <li class="list-group-item"><a href="${pageContext.request.contextPath}/JServlet?actionName=six">-------------总结---------------</a></li>
            </ul>
        </div>
    </div>
</div>
<script>
    function check() {
        if (confirm("注销?")){
            $.post("/patterns/JServlet",{
                    actionName:"clear"},
                function (data) {
                    if (data.search("clearSuc")!==-1){
                        window.location.href="index.jsp";
                    }else {
                        alert("对不起，注销失败！请重试。");
                    }
                }
            );
        }
    }
</script>
</body>
</html>